package com.kawa.kemanage.controller;

import com.kawa.kemanage.entity.News;
import com.kawa.kemanage.service.NewsService;
import com.kawa.kemanage.util.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import jakarta.websocket.server.PathParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.github.pagehelper.PageInfo;

import java.util.List;
import java.util.Map;

/**
 * @Author: KAIyo
 * @Date: 2025/6/3 0:29
 * @Version: v1.0.0
 * @Description: TODO
 **/
@Slf4j
@Validated
@RestController
@CrossOrigin
@RequestMapping({"/api/news", "/app/news"})
@Tag(name = "新闻管理接口", description = "新闻的增删改查等操作")
public class NewsController {
    @Autowired
    private NewsService newsService;

    /**
     * 以下均可以参考AuthController的test方法返回结果，可以自行使用postman测试test方法
     * 给你们稍微留出来一点间隔,免得到时候冲突冲到头晕
     */
    /**
     * 查询新闻，要分页查询，json格式返回，使用util文件夹下的Result进行包装
     */

    @Operation(summary = "获取新闻列表", description = "分页获取新闻列表，支持按分类筛选")
    @GetMapping("/list")
    @Cacheable(value = "news", key = "'list-' + #pageNo + '-' + #pageSize + '-' + #categoryId", unless = "#result == null")
    public Result queryAllNews(
            @Parameter(description = "页码，从1开始") @RequestParam(defaultValue = "1") Integer pageNo,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @Parameter(description = "分类ID") @RequestParam(required = false) String categoryId,
            @Parameter(description = "排序字段") @RequestParam(defaultValue = "modifyDate") String sortField,
            @Parameter(description = "排序方式：asc/desc") @RequestParam(defaultValue = "desc") String sortOrder) {
        try {
            return Result.success(newsService.getNewsList(pageNo, pageSize, categoryId, sortField, sortOrder));
        } catch (Exception e) {
            log.error("获取新闻列表失败", e);
            return Result.error("获取新闻列表失败：" + e.getMessage());
        }
    }

    @Operation(summary = "获取新闻详情", description = "根据新闻ID获取新闻详情")
    @GetMapping("/detail/{newsId}")
    @Cacheable(value = "news", key = "'detail-' + #newsId", unless = "#result == null")
    public Result getNewsDetail(
            @Parameter(description = "新闻ID") @PathVariable String newsId) {
        try {
            return Result.success(newsService.getNewsById(newsId));
        } catch (Exception e) {
            log.error("获取新闻详情失败", e);
            return Result.error("获取新闻详情失败：" + e.getMessage());
        }
    }

    /**
     * 发布新闻，json格式返回，使用util文件夹下的Result进行包装
     */
    @Operation(summary = "发布新闻", description = "发布新的新闻")
    @PostMapping("/publish")
    @CacheEvict(value = "news", allEntries = true)
    public Result addNews(@Valid @RequestBody News news) {
        try {
            boolean result = newsService.addNews(news);
            return result ? Result.success("发布成功") : Result.error("发布失败");
        } catch (Exception e) {
            log.error("发布新闻失败", e);
            return Result.error("发布新闻失败：" + e.getMessage());
        }
    }

    /**
     * 发布新闻并创建审核记录
     */
    @Operation(summary = "发布新闻并创建审核", description = "发布新闻并创建审核记录，等待管理员审核")
    @PostMapping("/publish-with-review")
    @CacheEvict(value = "news", allEntries = true)
    public Result addNewsWithReview(@Valid @RequestBody Map<String, Object> request) {
        try {
            News news = new News();
            news.setCategoryId(request.get("categoryId").toString());
            news.setTitle((String) request.get("title"));
            news.setSummary((String) request.get("summary"));
            news.setContent((String) request.get("content"));
            news.setPicPath((String) request.get("picPath"));
            Long authorId = Long.valueOf(request.get("authorId").toString());
            news.setAuthorId(authorId.intValue());

            // 获取草稿ID（如果有）
            Integer draftId = request.get("draftId") != null ?
                Integer.valueOf(request.get("draftId").toString()) : null;

            boolean result = newsService.addNewsWithReview(news, authorId, draftId);
            return result ? Result.success("发布成功，等待管理员审核") : Result.error("发布失败");
        } catch (Exception e) {
            log.error("发布新闻失败", e);
            return Result.error("发布新闻失败：" + e.getMessage());
        }
    }

    /**
     * 修改新闻，json格式返回结果，使用util文件夹下的Result进行包装
     */
    @Operation(summary = "更新新闻", description = "更新新闻信息")
    @PutMapping("/update")
    @CacheEvict(value = "news", allEntries = true)
    public Result updateNews(@Valid @RequestBody News news) {
        try {
            int updateNum = newsService.updateNews(news);
            return updateNum > 0 ? Result.success("更新成功") : Result.error("更新失败");
        } catch (Exception e) {
            log.error("更新新闻失败", e);
            return Result.error("更新新闻失败：" + e.getMessage());
        }
    }

    /**
     * 搜索新闻(已支持按分类搜索)
     * 点击分类时查询对应新闻
     * @param pageNo
     * @param pageSize
     * @param  categoryId 搜索内容
     * @return
     */
    @Operation(summary = "搜索新闻", description = "根据关键词和分类搜索新闻，支持分页和排序")
    @GetMapping("/searchNews")
    @Cacheable(value = "news", key = "'search-' + #keyword + '-' + #categoryId + '-' + #pageNo + '-' + #pageSize + '-' + #sortType", unless = "#result == null")
    public Result<PageInfo<News>> searchNews(
            @Parameter(description = "搜索关键词") 
            @RequestParam(required = false) String keyword,
            
            @Parameter(description = "分类ID") 
            @RequestParam(required = false) String categoryId,
            
            @Parameter(description = "页码，从1开始") 
            @RequestParam(defaultValue = "1") Integer pageNo,
            
            @Parameter(description = "每页大小") 
            @RequestParam(defaultValue = "12") Integer pageSize,
            
            @Parameter(description = "排序类型：relevance-相关度排序, time-时间排序") 
            @RequestParam(defaultValue = "relevance") String sortType) {
        try {
            // 确保页码从1开始
            if (pageNo < 1) {
                pageNo = 1;
            }
            
            // 限制每页大小范围
            if (pageSize < 1) {
                pageSize = 12;
            } else if (pageSize > 48) {
                pageSize = 48;
            }
            
            PageInfo<News> pageInfo = newsService.searchNews(keyword, categoryId, pageNo, pageSize, sortType);
            return Result.success(pageInfo);
        } catch (Exception e) {
            log.error("搜索新闻失败: {}", e.getMessage(), e);
            return Result.error("搜索新闻失败：" + e.getMessage());
        }
    }

    /**
     * 获取热门新闻列表
     *
     * @return 热门新闻列表
     */
    @Operation(summary = "获取热门新闻", description = "获取热门新闻列表")
    @GetMapping("/hot")
    @Cacheable(value = "news", key = "'hot'", unless = "#result == null")
    public Result getHotNews() {
        try {
            return Result.success(newsService.getHotNews());
        } catch (Exception e) {
            log.error("获取热门新闻失败", e);
            return Result.error("获取热门新闻失败：" + e.getMessage());
        }
    }

    /**
     * 获取热门新闻（按点赞数排序）
     */
    @Operation(summary = "获取热门新闻", description = "获取点赞数最多的前5条新闻")
    @GetMapping("/hotNews")
    @Cacheable(value = "news", key = "'hotNews'", unless = "#result == null")
    public Result getHotNews(@RequestParam(defaultValue = "5") Integer limit) {
        try {
            List<News> hotNews = newsService.getHotNews();
            return Result.success(hotNews);
        } catch (Exception e) {
            log.error("获取热门新闻失败", e);
            return Result.error("获取热门新闻失败：" + e.getMessage());
        }
    }

    /**
     * 删除新闻，json格式返回，使用util文件夹下的Result进行包装
     */
    @Operation(summary = "删除新闻", description = "根据ID删除新闻")
    @DeleteMapping("/delete/{id}")
    @CacheEvict(value = "news", allEntries = true)
    public Result deleteNews(@Parameter(description = "新闻ID") @PathVariable int id) {
        try {
            int deleteNum = newsService.deleteNewsById(id);
            return deleteNum > 0 ? Result.success("删除成功") : Result.error("删除失败");
        } catch (Exception e) {
            log.error("删除新闻失败", e);
            return Result.error("删除新闻失败：" + e.getMessage());
        }
    }


    /**
     * 根据用户名查看作品
     * @param authorId
     * @return
     */
    @RequestMapping("/getNewsByName")
    public  Result getNewsByName(@RequestParam(required = false) Integer authorId){
        return Result.success(newsService.getNewsByName(authorId));
    }

    /**
     * 获取个人收藏的作品
     * @return
     */
    @RequestMapping("/getNewsByFavorite")
    public  Result getNewsByFavorite(@RequestParam(required = false) Integer user_id){
        return  Result.success(newsService.getNewsByFavorite(user_id));
    }

    /**
     * 获取个人喜欢的作品
     * @return
     */
    @RequestMapping("/getNewsByLike")
    public  Result getNewsByLike(@RequestParam(required = false) Integer user_id){
        return  Result.success(newsService.getNewsByLike(user_id));
    }

    /**
     * 获取相关新闻（同类别随机新闻）
     */
    @Operation(summary = "获取相关新闻", description = "获取同类别的随机新闻。不传入newsId时返回所有随机新闻")
    @GetMapping({"/related/{newsId}", "/related"}) // 支持两种路径
    @Cacheable(value = "news", key = "'related-' + (#newsId != null ? #newsId : 'all') + '-' + #limit", unless = "#result == null")
    public Result getRelatedNews(
            @Parameter(description = "当前新闻ID", required = false)
            @PathVariable(required = false) String newsId, // 改为非必需

            @Parameter(description = "获取数量")
            @RequestParam(defaultValue = "4") Integer limit) {

        try {
            List<News> relatedNews = newsService.getRelatedNews(newsId, limit);
            return Result.success(relatedNews);
        } catch (Exception e) {
            log.error("获取相关新闻失败", e);
            return Result.error("获取相关新闻失败：" + e.getMessage());
        }
    }

}
